package com.fishingwithme.android.ui.screens.my

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.draggable
import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavController
import androidx.paging.compose.collectAsLazyPagingItems
import coil.compose.rememberAsyncImagePainter
import com.fishingwithme.android.R
import com.fishingwithme.android.data.local.PreferencesManager
import com.fishingwithme.android.data.model.User
import com.fishingwithme.android.navigation.FishingNavigation
import com.fishingwithme.android.ui.screens.my.points.CreditScreen
import com.fishingwithme.android.ui.theme.AppDimensions
import com.fishingwithme.android.ui.viewmodels.MyCircleViewModel
import com.fishingwithme.android.ui.viewmodels.MyHarvestViewModel
import com.fishingwithme.android.ui.viewmodels.MySpotsViewModel
import dagger.hilt.android.EntryPointAccessors
import kotlin.math.roundToInt

// Tab definitions
sealed class MyTab(val index: Int, val label: String, val role: String) {
    object MySpots : MyTab(0, "my_spots", "ROLE_USER")
    object Collected : MyTab(1, "collect", "ROLE_USER")
    object MyHarvests : MyTab(2, "my_harvest", "ROLE_USER")
    object MyCircles : MyTab(3, "my_circle", "ROLE_CIRCLE_MAINTAINER")

    companion object {

        fun allTabs(): List<MyTab> = listOf(MySpots, Collected, MyHarvests, MyCircles)
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MyScreen(navController: NavController) {
    // 获取PreferencesManager实例
    val context = LocalContext.current
    val preferencesManager = EntryPointAccessors.fromApplication(
        context.applicationContext,
        MyScreenHiltEntryPoint::class.java
    ).preferencesManager()

    // Get user data
    val user by preferencesManager.getLoginUserObj().collectAsState(initial = null)

    var selectedTab by remember { mutableStateOf(0) }

    // ViewModels for data loading
    val spotsViewModel: MySpotsViewModel = hiltViewModel()
    val harvestViewModel: MyHarvestViewModel = hiltViewModel()
    val circleModel: MyCircleViewModel = hiltViewModel()

    // Track which tabs have been initialized
    var initializedTabs by remember { mutableStateOf(setOf<Int>()) }

    // Initialize the first tab immediately
    LaunchedEffect(Unit) {
        initializedTabs = setOf(selectedTab)
    }

    // Update initialized tabs when selected tab changes
    LaunchedEffect(selectedTab) {
        initializedTabs = initializedTabs + selectedTab
    }

    // Create separate lazy paging items for each tab - but only initialize when tab is selected
    val mySpots = remember(spotsViewModel, initializedTabs) {
        if (initializedTabs.contains(MyTab.MySpots.index)) {
            spotsViewModel.getSpots(false)
        } else {
            null
        }
    }

    val collectedSpots = remember(spotsViewModel, initializedTabs) {
        if (initializedTabs.contains(MyTab.Collected.index)) {
            spotsViewModel.getSpots(true)
        } else {
            null
        }
    }

    val myHarvests = remember(harvestViewModel, initializedTabs) {
        if (initializedTabs.contains(MyTab.MyHarvests.index)) {
            harvestViewModel.getMyHarvests()
        } else {
            null
        }
    }

    val myCircles = remember(circleModel, initializedTabs) {
        if (initializedTabs.contains(MyTab.MyCircles.index)) {
            circleModel.getMyCircles()
        } else {
            null
        }
    }

    // State for drawer expansion
    var isDrawerExpanded by remember { mutableStateOf(false) }

    // State to track if drawer is in initial position
    var isInitialPosition by remember { mutableStateOf(true) }
    
    // Reference to the LazyColumn state for scroll position tracking
    val lazyListState = rememberLazyListState()
    
    // State to store measured header height
    var headerHeight by remember { mutableStateOf(0f) }

    // Box container for the entire screen
    Box(
        modifier = Modifier.fillMaxSize()
    ) {
        // Fixed Header section - always visible
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentHeight()
                .zIndex(2f) // Ensure header is above drawer when collapsed
                .background(MaterialTheme.colorScheme.surface)
                .onGloballyPositioned { coordinates ->
                    // Measure the actual height of the header
                    headerHeight = coordinates.size.height.toFloat()
                }
        ) {
            UserInfoSection(user, navController)
            CreditScreen()
        }

        // Drawer section - scrollable and can cover the entire screen
        Box(
            modifier = Modifier
                .fillMaxWidth()
                .fillMaxHeight()
                .offset { 
                    IntOffset(
                        0, 
                        if (isDrawerExpanded) 0 else headerHeight.roundToInt()
                    ) 
                }
                .zIndex(3f) // Ensure drawer is above header when expanded
                .draggable(
                    state = rememberDraggableState { delta ->
                        // Only allow dragging if we're at the top of the scroll
                        val isAtTop = lazyListState.firstVisibleItemIndex == 0 && 
                                     lazyListState.firstVisibleItemScrollOffset == 0
                        
                        if (isAtTop) {
                            // Detect swipe direction
                            if (delta < -50) { // Swiping up
                                isDrawerExpanded = true
                                isInitialPosition = false
                            } else if (delta > 50) { // Swiping down
                                isDrawerExpanded = false
                                isInitialPosition = true
                            }
                        }
                    },
                    orientation = Orientation.Vertical,
                    onDragStopped = { velocity ->
                        // Snap to either fully expanded or collapsed position
                        val isAtTop = lazyListState.firstVisibleItemIndex == 0 && 
                                     lazyListState.firstVisibleItemScrollOffset == 0
                        
                        when {
                            // If swiping up (negative velocity), expand fully
                            velocity < -1000f -> {
                                isDrawerExpanded = true
                                isInitialPosition = false
                            }
                            // If swiping down (positive velocity) and at top of scroll, collapse
                            velocity > 1000f && isAtTop -> {
                                isDrawerExpanded = false
                                isInitialPosition = true
                            }
                            // Otherwise, keep current state
                        }
                    }
                )
        ) {
            // Fixed TabBar at the top of the drawer - always visible
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .wrapContentHeight()
                    .background(MaterialTheme.colorScheme.surface)
                    .zIndex(4f) // Ensure TabBar is always on top
            ) {
                TabBarSection(selectedTab = selectedTab, user = user) { newTab ->
                    selectedTab = newTab
                }
            }

            // Scrollable content area below the TabBar - with background only for content
            LazyColumn(
                state = lazyListState,
                modifier = Modifier
                    .fillMaxSize()
                    .padding(top = AppDimensions.SPACING_40) // Approximate height of TabBar
                    .background(MaterialTheme.colorScheme.background) // Background only for content area
            ) {
                // Content area based on selected tab
                item {
                    Column(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(horizontal = AppDimensions.SPACING_16)
                    ) {
                        // Pre-collect paging items to ensure consistent structure
                        val mySpotsItems = mySpots?.collectAsLazyPagingItems()
                        val collectedSpotsItems = collectedSpots?.collectAsLazyPagingItems()
                        val myHarvestsItems = myHarvests?.collectAsLazyPagingItems()
                        val myCirclesItems = myCircles?.collectAsLazyPagingItems()

                        // Render only the active tab content to prevent whole page refresh
                        when (selectedTab) {
                            MyTab.MySpots.index -> {
                                if (mySpotsItems != null) {
                                    MySpotsTabContent(
                                        spots = mySpotsItems,
                                        navController = navController
                                    )
                                } else {
                                    // Loading state for uninitialized tab
                                    Box(
                                        modifier = Modifier
                                            .fillMaxSize(),
                                        contentAlignment = Alignment.Center
                                    ) {
                                        CircularProgressIndicator()
                                    }
                                }
                            }

                            MyTab.Collected.index -> {
                                if (collectedSpotsItems != null) {
                                    MySpotsTabContent(
                                        spots = collectedSpotsItems,
                                        navController = navController
                                    )
                                } else {
                                    // Loading state for uninitialized tab
                                    Box(
                                        modifier = Modifier
                                            .fillMaxSize(),
                                        contentAlignment = Alignment.Center
                                    ) {
                                        CircularProgressIndicator()
                                    }
                                }
                            }

                            MyTab.MyHarvests.index -> {
                                if (myHarvestsItems != null) {
                                    MyHarvestsTabContent(
                                        harvests = myHarvestsItems,
                                        navController = navController
                                    )
                                } else {
                                    // Loading state for uninitialized tab
                                    Box(
                                        modifier = Modifier
                                            .fillMaxSize(),
                                        contentAlignment = Alignment.Center
                                    ) {
                                        CircularProgressIndicator()
                                    }
                                }
                            }

                            MyTab.MyCircles.index -> {
                                if (myCirclesItems != null) {
                                    MyCirclesTabContent(
                                        circles = myCirclesItems,
                                        navController = navController
                                    )
                                } else {
                                    // Loading state for uninitialized tab
                                    Box(
                                        modifier = Modifier
                                            .fillMaxSize(),
                                        contentAlignment = Alignment.Center
                                    ) {
                                        CircularProgressIndicator()
                                    }
                                }
                            }
                        }
                    }
                }
                // Footer spacing
                item {
                    Spacer(modifier = Modifier.height(AppDimensions.SPACING_32))
                }
            }
        }
    }
}


@Composable
private fun UserInfoSection(user: User?, navController: NavController) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(AppDimensions.SPACING_16),
        verticalAlignment = Alignment.CenterVertically
    ) {
        // User icon (clickable to navigate to settings)
        Box(
            modifier = Modifier
                .size(AppDimensions.ICON_SIZE_60)
                .clip(RoundedCornerShape(AppDimensions.ROUNDED_CORNER_50))
                .clickable {
                    navController.navigate(FishingNavigation.USER_SETTINGS)
                }
                .background(MaterialTheme.colorScheme.primary),
            contentAlignment = Alignment.Center
        ) {
            Image(
                painter = rememberAsyncImagePainter(user?.avatarUrl),
                contentDescription = "User Avatar",
                modifier = Modifier.fillMaxSize(),
                contentScale = ContentScale.Crop
            )
        }

        Spacer(modifier = Modifier.width(AppDimensions.SPACING_16))

        // User name
        Text(
            text = user?.nickname ?: stringResource(R.string.username),
            style = MaterialTheme.typography.titleMedium
        )
    }
}

@Composable
private fun TabBarSection(selectedTab: Int, user: User?, onTabSelected: (Int) -> Unit) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = AppDimensions.SPACING_16),
        horizontalArrangement = Arrangement.SpaceEvenly
    ) {
        MyTab.allTabs().forEach { tab ->
            if (user?.roles?.contains(tab.role) ?: false)
                Text(
                    text = stringResource(getTabStringResource(tab)),
                    style = if (selectedTab == tab.index) MaterialTheme.typography.titleMedium else MaterialTheme.typography.bodyMedium,
                    color = if (selectedTab == tab.index) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.onSurface,
                    modifier = Modifier
                        .clickable {
                            onTabSelected(tab.index)
                        }
                        .padding(AppDimensions.SPACING_12)
                )
        }
    }
}


private fun getTabStringResource(tab: MyTab): Int {
    return when (tab) {
        MyTab.MySpots -> R.string.my_spots
        MyTab.Collected -> R.string.collect
        MyTab.MyHarvests -> R.string.my_harvest
        MyTab.MyCircles -> R.string.my_circle
    }
}

@dagger.hilt.EntryPoint
@dagger.hilt.InstallIn(dagger.hilt.components.SingletonComponent::class)
interface MyScreenHiltEntryPoint {
    fun preferencesManager(): PreferencesManager
}